@file:Suppress("unused")
package com.meelive.channel.reader

import com.meelive.channel.common.ChannelConstants
import com.meelive.channel.common.V2SchemeUtil
import com.meelive.channel.common.verify.ApkSignatureSchemeV2Verifier
import java.io.File
import java.io.IOException
import java.io.UnsupportedEncodingException
import java.nio.ByteBuffer
import java.nio.charset.Charset
import java.util.*

/**
 * Created by leontli on 17/1/19.
 *
 *
 * 针对V2签名块的Id-Value序列进行读取操作
 */
object IdValueReader {
    /**
     * get string value by id
     *
     * @param channelFile
     * @param id
     * @return
     */
    fun getStringValueById(channelFile: File?, id: Int): String? {
        if (channelFile == null || !channelFile.exists() || !channelFile.isFile) {
            return null
        }
        val buffer = getByteValueById(channelFile, id)
        try {
            if (buffer != null && buffer.isNotEmpty()) {
                return String(buffer, Charset.forName(ChannelConstants.CONTENT_CHARSET))
            }
        } catch (e: UnsupportedEncodingException) {
            e.printStackTrace()
        }
        return null
    }

    /**
     * get byte[] value from apk by id
     *
     * @param channelFile
     * @param id
     * @return
     */
    fun getByteValueById(channelFile: File?, id: Int): ByteArray? {
        if (channelFile == null || !channelFile.exists() || !channelFile.isFile) {
            return null
        }
        val value = getByteBufferValueById(channelFile, id)
        println("getByteValueById , id = $id , value = $value")
        return if (value != null) {
            Arrays.copyOfRange(
                value.array(),
                value.arrayOffset() + value.position(),
                value.arrayOffset() + value.limit()
            )
        } else null
    }

    /**
     * get ByteBuffer value from apk by id
     *
     * @param channelFile
     * @param id
     * @return
     */
    fun getByteBufferValueById(channelFile: File?, id: Int): ByteBuffer? {
        if (channelFile == null || !channelFile.exists() || !channelFile.isFile) {
            return null
        }
        val idValueMap = getAllIdValueMap(channelFile)
        println("getByteBufferValueById , destApk " + channelFile.absolutePath + " IdValueMap = " + idValueMap)
        return idValueMap?.get(id)
    }

    /**
     * find all Id-Value Pair from Apk
     *
     * @param channelFile
     * @return
     */
    fun getAllIdValueMap(channelFile: File?): Map<Int, ByteBuffer>? {
        if (channelFile == null || !channelFile.exists() || !channelFile.isFile) {
            return null
        }
        try {
            val apkSigningBlock = V2SchemeUtil.getApkSigningBlock(channelFile)
            return V2SchemeUtil.getAllIdValue(apkSigningBlock)
        } catch (e: IOException) {
            e.printStackTrace()
        } catch (e: ApkSignatureSchemeV2Verifier.SignatureNotFoundException) {
            //e.printStackTrace();
            println("APK : " + channelFile.absolutePath + " not have apk signature block")
        }
        return null
    }
}